﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Plugins.Engine
{
    /// <summary>
    /// This class is an implementation detail of the MessageToActionsMap class.
    /// </summary>
    [Serializable]
    public abstract class PluginWeakReference
    {
        private readonly WeakReference _obj;
        private readonly MethodInfo _method;
        private readonly Type _type;

        protected PluginWeakReference(WeakReference obj, MethodInfo method, Type type)
        {
            this._obj = obj;
            this._method = method;
            this._type = type;
        }

        protected void DynamicInvoke(Delegate actionInvoker)
        {
            if (_method.IsStatic)
            {
                actionInvoker.DynamicInvoke(Delegate.CreateDelegate(_type, _method));
            }
            else
            {
                actionInvoker.DynamicInvoke(Delegate.CreateDelegate(_type, _obj.Target, _method));
            }
        }

        public void DynamicInvoke(Delegate actionInvoker, Type type)
        {
            if (_type == type)
            {
                DynamicInvoke(actionInvoker);
            }
        }

        public bool Contains(object target, MethodInfo method, Type type)
        {
            return _type == type && _method == method && (!_obj.IsAlive || _obj.Target == target);
        }
    }

    public sealed class PluginWeakReference<T> : PluginWeakReference
    {
        public PluginWeakReference(object value, MethodInfo method)
            : base(new WeakReference(value), method, typeof(T))
        {
        }

        public void DynamicInvoke(Action<T> actionInvoker)
        {
            base.DynamicInvoke(actionInvoker);
        }
    }
}
